using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace Edge.Common.Utils
{
    [AttributeUsage(AttributeTargets.Field)]
    public class NullValueAttribute : Attribute
    {
    }

    /// <summary>
    /// Summary description for EnumUtils.
    /// </summary>
    public class EnumUtils
    {
        protected EnumUtils()
        {
        }

        #region null values for enum's

        public static bool IsNull(Enum value)
        {
            return GetAttribute(value, typeof(NullValueAttribute)) != null;
        }

        public static object GetAttribute(Enum value, Type attrType)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            object[] attributes = fi.GetCustomAttributes(attrType, false);
            return attributes.Length > 0 ? attributes[0] : null;
        }

        public static string GetDescriptionAttribute(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            return GetDescriptionAttribute(fi);
        }


        public static string GetDescriptionAttribute(FieldInfo fi)
        {
            object[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? ((DescriptionAttribute)(attributes[0])).Description : null;
        }

        public static SortedList<string, int> GetEnumDataSource<T>() where T : struct
        {
            Type myEnumType = typeof(T);
            if (myEnumType.BaseType != typeof(Enum))
            {
                throw new ArgumentException("Type T must inherit from System.Enum.");
            }

            SortedList<string, int> returnCollection = new SortedList<string, int>();
            string[] enumNames = Enum.GetNames(myEnumType);
            string[] enumDescriptions = new string[enumNames.Length];
            int i = 0;
            foreach (FieldInfo fi in myEnumType.GetFields())
            {
                if (fi.FieldType.FullName == myEnumType.FullName)
                {
                    enumDescriptions[i] = GetDescriptionAttribute(fi);
                    i++;
                }
            }
            
            for (i = 0; i < enumNames.Length; i++)
            {
                returnCollection.Add(enumDescriptions[i],
                    (int)Enum.Parse(myEnumType, enumNames[i]));
            }
            return returnCollection;
        }


        #endregion

        public static T Swap<T>(T first, T second, T value)
        //	        where T : Enum
        {
            return value.Equals(first) ? second : first;
        }

        public static bool IsNullableEnum(Type type)
        {
            if (type == null)
                throw new ArgumentException("type");

            return (type.IsGenericType &&
                    type.GetGenericTypeDefinition() == typeof(Nullable<>) &&
                    (type.GetGenericArguments()[0].IsEnum));
        }

    }
}
